package com.sojson.util.lock.config.redisson;

import java.io.IOException;
import java.util.List;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

import com.sojson.util.cache.redis.RedisCacheUtilInterface;
import com.sojson.util.cache.redis.bean.DbRds;
import com.sojson.util.cache.redis.condition.RedisCondition;

/**
 * Redisson配置类<BR>
 * (如果出现了LEAK: hashedwheelTimer.release() was not called before it’s garbage-collected. Enable advanced leak)<BR>
 * 网上搜到的是因为内存不够大导致
 *
 * @author liu
 * @date 2021-07-19
 */
@Configuration
public class RedissonConfig {

    /**
     * 对 Redisson 的使用都是通过 RedissonClient 对象
     * @return
     * @throws IOException
     */
    @Bean(destroyMethod = "shutdown") // 服务停止后调用 shutdown 方法。
    @Conditional(RedisCondition.class)
    public RedissonClient redisson() throws IOException {
        // 创建配置
        Config config = new Config();

        // 初始化连接信息
        // TODO
        init(config);
        // initCluster(config);

        return Redisson.create(config);
    }

    /**
     * 初始化连接信息
     *
     * @param config
     * @return
     */
    private void init(Config config) {
        List<DbRds> dbs = RedisCacheUtilInterface.dbs;
        int size = dbs.size();
        if (size < 1) {
        } else if (size == 1) {
            initSingle(config);
        } else {
            initCluster(config);
        }
    }

    /**
     * 初始化连接信息(单机模式)
     *
     * @param config
     * @return
     */
    private void initSingle(Config config) {
        List<DbRds> dbs = RedisCacheUtilInterface.dbs;
        // 获取第一个数据源
        DbRds dbRds = dbs.get(0);

        // 单机模式
        // 根据 Config 创建出 RedissonClient 示例
        SingleServerConfig serverConfig = config.useSingleServer();
        // 设置地址
        serverConfig.setAddress(getUrl(dbRds));
        // 设置密码
        serverConfig.setPassword(dbRds.getPassword());
    }

    /**
     * 初始化连接信息(集群模式)
     *
     * @param config
     * @return
     */
    private void initCluster(Config config) {
        List<DbRds> dbs = RedisCacheUtilInterface.dbs;
        // 获取第一个数据源
        DbRds dbRds = dbs.get(0);

        // 集群模式
        // 根据 Config 创建出 RedissonClient 示例
        ClusterServersConfig useClusterServers = config.useClusterServers();
        for (int i = 0; i < dbs.size(); i++) {
            DbRds db = dbs.get(i);
            // 设置地址
            useClusterServers.addNodeAddress(getUrl(db));
        }
        // 设置密码
        useClusterServers.setPassword(dbRds.getPassword());
    }

    /**
     * 获取连接地址
     *
     * @param db
     * @return
     */
    private String getUrl(DbRds db) {
        return "redis://" + db.getHost() + ":" + db.getPort();
    }

}